﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using OpenTK.Graphics.OpenGL;
using OpenTK.Mathematics;

namespace OpenTKBasics.AssimpNet
{
    public class Mesh2
    {
        private int vertexBuffHandle;        //顶点缓存句柄   VBO
        private int vertexArrayHandle;       //顶点列表句柄   VAO句柄
        private int elementBuffHandle;      //顶点元素句柄   EAO句柄

        public Vertex[] vertices;
        public uint[] indices;
        public Texture[] textures;

        int VertexSize = 8;
        public Mesh2(float[] _vertices, uint[] _indices)
        {
            //unsafe { VertexSize = sizeof(Vertex); }
            this.vertices = new Vertex[_vertices.Length / VertexSize];
            for (int i = 0; i < _vertices.Length / VertexSize; i++)
            {
                Vertex vertex = new Vertex();
                vertex.Position = new Vector3(_vertices[i * VertexSize], _vertices[i * VertexSize + 1], _vertices[i * VertexSize + 2]);
                vertex.Normal = new Vector3(_vertices[i * VertexSize + 3], _vertices[i * VertexSize + 4], _vertices[i * VertexSize + 5]);
                vertex.TexCoords = new Vector2(_vertices[i * VertexSize + 6], _vertices[i * VertexSize + 7]);
                this.vertices[i] = vertex;//.Append();
            }
            this.indices = _indices;
            this.textures = new Texture[0];
            SetupMesh();
        }
        public Mesh2(float[] _vertices, uint[] _indices, Texture[] _textures)
        {
            unsafe { VertexSize = sizeof(Vertex); }
            this.vertices = new Vertex[_vertices.Length / VertexSize];
            for (int i = 0; i < _vertices.Length / VertexSize; i++)
            {
                Vertex vertex = new Vertex();
                vertex.Position = new Vector3(i * VertexSize, i * VertexSize + 1, i * VertexSize + 2);
                vertex.Normal = new Vector3(i * VertexSize + 3, i * VertexSize + 4, i * VertexSize + 5);
                vertex.TexCoords = new Vector2(i * VertexSize + 6, i * VertexSize + 7);
                this.vertices.Append(vertex);
            }
            this.indices = _indices;
            this.textures = _textures;
            SetupMesh();
        }
        public Mesh2(Vertex[] _vertices, uint[] _indices, Texture[] _textures)
        {
            this.vertices = _vertices;
            this.indices = _indices;
            this.textures = _textures;
            SetupMesh();
        }

        public void Draw(Shader shader)
        {
            foreach (Texture texture in textures)
            {
                if (texture.type == "texture_diffuse")
                {
                    GL.ActiveTexture(TextureUnit.Texture0);
                    GL.BindTexture(TextureTarget.Texture2D, texture.id);
                    shader.SetInt("material.diffuse", 0);
                }
                else if (texture.type == "texture_specular")
                {
                    GL.ActiveTexture(TextureUnit.Texture1);
                    GL.BindTexture(TextureTarget.Texture2D, texture.id);
                    shader.SetInt("material.sepcular", 1);
                }

            }
            GL.BindVertexArray(this.vertexArrayHandle);
            GL.DrawElements(PrimitiveType.Triangles, indices.Length, DrawElementsType.UnsignedInt, 0);
            GL.BindVertexArray(0);

            //GL.ActiveTexture(TextureUnit.Texture0);
        }

        private void SetupMesh()
        {
            //VAO
            this.vertexArrayHandle = GL.GenVertexArray();
            GL.BindVertexArray(this.vertexArrayHandle);

            //VBO
            this.vertexBuffHandle = GL.GenBuffer();//建立一个顶点缓存句柄
            GL.BindBuffer(BufferTarget.ArrayBuffer, this.vertexBuffHandle);//将顶点缓存句柄绑定在缓存实例
            //bind
            //int VertexN = 0;
            //unsafe { VertexSize = sizeof(Vertex); }
            GL.BufferData(BufferTarget.ArrayBuffer,
               vertices.Length * VertexSize, vertices,
               BufferUsageHint.StaticDraw);  //将顶点位置放入缓存实例
            //EBO
            this.elementBuffHandle = GL.GenBuffer();
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, elementBuffHandle);
            GL.BufferData(BufferTarget.ElementArrayBuffer, indices.Length * sizeof(uint), indices, BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ElementArrayBuffer, 0);

            // 顶点位置
            int vertexLoc = 0;
            GL.EnableVertexAttribArray(vertexLoc);  // 顶点的缓存组  组号0
            GL.VertexAttribPointer(vertexLoc, 3, VertexAttribPointerType.Float, false, VertexSize * sizeof(float), 0);

            // 顶点法线
            int normalLoc = 1;
            GL.EnableVertexAttribArray(normalLoc);  // 顶点的缓存组  组号0
            GL.VertexAttribPointer(normalLoc, 3, VertexAttribPointerType.Float, false, VertexSize * sizeof(float), 3 * sizeof(float));

            // 顶点纹理坐标
            int textureLoc = 2;
            GL.EnableVertexAttribArray(textureLoc);  // 顶点的缓存组  组号0
            GL.VertexAttribPointer(textureLoc, 2, VertexAttribPointerType.Float, false, VertexSize * sizeof(float), 6 * sizeof(float));

            GL.EnableVertexAttribArray(0);
            GL.EnableVertexAttribArray(1);
            GL.EnableVertexAttribArray(2);

            GL.BindVertexArray(0);

        }

    }

  



}
